package model

import (
	"encoding/json"
	_ "time"
)

var (
	cache map[string]map[uint]uint
)

func init() {
	cache = make(map[string]map[uint]uint)
}

//Machine 结构体
type Base_machine struct {
	Tid        int    `json:"tid"`
	Machine_ip string `json:"machine_ip"`
	Machine_no string `json:"machine_no"`

	Spindle_count int `json:"spindle_count"`
	Spindle_mode  int `json:"spindle_mode"`
	Spindle_speed int `json:"boot_mode"`

	Boot_delay int `json:"boot_delay"`
	Boot_cond  int `json:"boot_cond"`

	Dtime string `json:"dtime"`
	//Uploaded    int    `json:"uploaded"`
	//Upload_time string `json:"upload_time"`
}

func (r *Base_machine) Convert_2_virtual_spin_no(real_num uint) uint {

	virtual_num := real_num
	num := real_num

	if r.Spindle_mode == 1 {
		return real_num
	}

	spindles_per_side := uint(r.Spindle_count / 2)

	if r.Spindle_mode == 2 {
		if num <= spindles_per_side {
			virtual_num = spindles_per_side + num
		} else {
			virtual_num = spindles_per_side - num
		}
	}

	if r.Spindle_mode == 3 {
		virtual_num = 2*spindles_per_side - num + 1
	}

	if r.Spindle_mode == 4 {
		if num <= spindles_per_side {
			virtual_num = spindles_per_side + num
		} else {
			virtual_num = num - spindles_per_side
		}
	}

	return virtual_num
}

func (r *Base_machine) store_spindle_status(spindle_no uint, status uint) {

	mtree, ok := cache[r.Machine_ip]
	if ok == false {
		cache[r.Machine_ip] = make(map[uint]uint)
		mtree = cache[r.Machine_ip]
	}

	pre_status, ok := mtree[spindle_no]
	if ok == false {
		mtree[spindle_no] = status
		return
	}

	if pre_status != status {
		mtree[spindle_no] = status
	}
}

// 将 原始纱锭状态数据 过滤出来， 保存到 cache 中
func (r *Base_machine) Interpret(data []byte, offset uint16, count uint16) {

	length := uint16(len(data))
	var tail uint16 = 1
	if (length % 2) == 0 {
		tail = 0
	}

	var loop_times uint16 = uint16(length/2) + tail
	if count < loop_times {
		loop_times = count
	}

	var position = int(offset) * 4
	var time uint16 = 0
	for ; time < loop_times; time++ {
		virtual_index0 := r.Convert_2_virtual_spin_no(uint(position + 1))
		virtual_index1 := r.Convert_2_virtual_spin_no(uint(position + 2))
		virtual_index2 := r.Convert_2_virtual_spin_no(uint(position + 3))
		virtual_index3 := r.Convert_2_virtual_spin_no(uint(position + 4))

		if (time*2+1) < length && (data[time*2+1]&0x0f) > 0 {
			r.store_spindle_status(virtual_index0, uint(data[time*2+1]&0x0f))
		}
		if (time*2+1) < length && ((data[time*2+1]&0xf0)>>4) > 0 {
			r.store_spindle_status(virtual_index1, uint((data[time*2+1]&0xf0)>>4))
		}
		if (time*2) < length && (data[time*2]&0x0f) > 0 {
			r.store_spindle_status(virtual_index2, uint(data[time*2]&0x0f))
		}
		if (time*2) < length && ((data[time*2]&0xf0)>>4) > 0 {
			r.store_spindle_status(virtual_index3, uint((data[time*2]&0xf0)>>4))
		}

		position += 4
	}
}

func (r *Base_machine) DumpCache() string {

	mtree, ok := cache[r.Machine_ip]
	if ok == false {
		return "{}"
	}

	json_obj, _ := json.Marshal(mtree)

	return string(json_obj)
}

func (r *Base_machine) ClearCache() {
	cache[r.Machine_ip] = make(map[uint]uint)
}
